查看原文
其他

ELF文件注入shellcode原理与实现

哆啦安全 2022-11-13

The following article is from 安全狗的自我修养 Author haidragon

介绍

    代码注入(英语:Code injection)是一种肇因于处理非法资料的电脑臭虫应用。代码注入可被攻击者用来导入代码到某特定的计算机程序,以改变程序的运行进程或目的。代码注入攻击的结果可以是灾难性的。


    可执行与可链接格式 (英语:Executable and Linkable Format,缩写为ELF),常被称为ELF格式,在计算机科学中,是一种用于可执行文件、目标文件、共享库和核心转储(core dump)的标准文件格式。

1999年,被86open项目选为x86架构上的类Unix操作系统的二进制文件格式标准,用来取代COFF。因其可扩展性与灵活性,也可应用在其它处理器、计算机系统架构的操作系统上。


    shellcode是一段用于利用软件漏洞而执行的代码,shellcode为16进制之机械码,以其经常让攻击者获得shell而得名。shellcode常常使用机器语言编写。可在暂存器eip溢出后,塞入一段可让CPU执行的shellcode机械码,让电脑可以执行攻击者的任意指令。

    

原理

    上面也讲了几个概念,本文讲的是在ELF(可执行文件,类似于windows的exe PE文件。)文件中注入一段可以执行的shellcode(可能是恶意后门,可能新增的功能插件。)

,目的是在程序(ELF)启动前先执行我们注入的shellcode程序达到劫持(留后门)或启动前修复程序bug的作用。

实现

    通过前面介绍这么多有一些同学可能刚刚入门读起来比较抽象,不要紧,这里我在讲注入实现前我们先从计算机发展历史说起。

    大家都知道以前电脑是打孔的(像传送带一样。),同时电脑也是电器,所以电只有正与负,我们就用0和1代替,然而0与1就俩个数字表示东西太少了,因此就出现各种进制转换,比如我们习惯性是10进制,而计算机是16进制占4四字节(一个字节是8位,就是00000000)前面加一个0x符号,比如0x10。以前编写程序(世界上第一个程序员是女性。)就是用这种0与1来编写。慢慢的发现这种不好记,就发明了汇编(不一样的架构有不一样的指令集,这里讲pc x86构架。)也就是提取特征,比如50 就表示push eax,我们写shellcode就是用汇编去写,后面又发明了更高级的c/c++语言,然后用这些语言去写肯定要用一个工具去做翻译,把它翻译成16进制,也就所谓的编译器。

    好了讲了这么多,其实ELF就是一个0与1组成的一个可以执行的文件,那为什么要搞一个ELF文件格式呢,我们想想,一个程序不可能在一台电脑(同一种类型的操作系统)上运行,你写的不一字会在其它电脑上能运行,那我们就定一个规矩一个文件格式,操作系统只要按这个格式去取指令执行就ok了,因此就有了各种文件格式,类unix系统是ELF,windows是PE,macOS是macho,有了文件格式那方便很多,因为程序一般包含其它资源比如图片、音乐等等,因此我们现在看看ELF文件格式是什么样的,如下图所示。

它主要是由文件头加各种段组成,文件头用来索引后面的各种段(或者说节,详细教程可以联系作者。),段一般有代码段、重定位段、符号等等,我们写一个测试程序然后用自己写的解析工具读他的信息如下图所示。

#include <stdio.h>
int main(int argc,char * argv[]) { main1(); return 0;}
int main1() { printf("haidragon_study! call main1\n"); return 0;}

    下面我们正式开始实现注入逻辑,思路是我们先解析整个ELF文件把各种信息保存到缓冲区中,然后我们读取要注入的shellcode文件(opcode),遍历整个节,因为ELF这件中有好多节我们实际是用不到的,但是他也会生成因此就可以利用这段空间保存我们的shellcode,然而这种有利用空间的节肯定是有限的可能shellcode比较大,所以我们是先找出这些可利用空间节的大小如果找到适合的能装下shellcode的就利用起来写到那里,如果空间小了那我们就新增一节名声可以叫作shellcode节,最后要做的就是劫持入口把入口指向shellcode的起始偏移,执行shellcode,同时在shellcode执行完的最后跳回原来入口(要先保存入口地址),开始执行运行程序。

 这里就准备了一段编译好的shellcode(如何写这里不说了。)功能是打印一个hello world,shellcode如下图所示。

现在开始写代码逻辑,提供读入被注入的文件和这个shellcode文件,如下图所示。

然后就是先保存入口(入到shellcode最后面),再找节中是否有无用的节然后判断大小,没有适合的就新增一节,把节的所有信息修改成代码节的信息(因为shellcode是代码要拿来执行的,必须要设置成代码节信息,告诉加载器),最后就是替换入口,如下图所示。

运行后我们看看生成的程序,如下图所示。

看看修改后的文件,如下图所示。

     到这里我们算是把一个简单的shellcode注入器实现了,文章中有很多没有讲到的,还有代码不可能全添出来太长了,可以直接联系作者,相关系统教程如下图所示,长期更新。


关注公众号获取更多最新文章

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存